package channel

import (
	"context"
	"errors"
	channel_define "go-iot-gateway/internal/channel/define"
	"sync"
)

var instance *ChannelManager
var once sync.Once

type ChannelManager struct {
	channels  map[string]channel_define.ConnectChannel
	Ctx       context.Context
	cancelCtx context.CancelFunc
	lock      sync.Mutex
}

// InitManager 初始化通道
func InitManager(ctx context.Context) {
	once.Do(func() {
		cancelCtx, cancelCtxFunc := context.WithCancel(ctx)
		instance = &ChannelManager{
			Ctx:       cancelCtx,
			channels:  make(map[string]channel_define.ConnectChannel),
			cancelCtx: cancelCtxFunc,
		}
	})
}

// RunChannel 启动一个通道
func (manager *ChannelManager) RunChannel(channel channel_define.ConnectChannel) error {
	if _, ok := manager.channels[channel.Info().ChlId]; ok {
		return errors.New("已经注册了")
	}

	manager.lock.Lock()
	defer manager.lock.Unlock()

	if _, ok := manager.channels[channel.Info().ChlId]; ok {
		return errors.New("已经注册了")
	}

	manager.channels[channel.Info().ChlId] = channel

	go func() {
		//打开通道
		channel.Open()
	}()

	return nil
}

//todo 重启通道

// CloseChannelById 关闭某个通道
func (manager *ChannelManager) CloseChannelById(chl_id string) {
	//todo, 关闭后移除
}

// CloseAllChannel 关闭所有通道
func (manager *ChannelManager) CloseAllChannel() {
	//todo 异步返回
	for _, channel := range manager.channels {
		if channel != nil {
			go func() {
				channel.Close()
			}()
		}
	}
}

// GetChannelById 根据通道id 获取通道
func (manager *ChannelManager) GetChannelById(chl_id string) channel_define.ConnectChannel {
	if ch, ok := manager.channels[chl_id]; ok {
		return ch
	}
	return nil
}

// Manager 获取管理器
func Manager() *ChannelManager {
	if instance == nil {
		panic("管理器未初始化")
	}
	return instance
}
